#pragma once
#include <cstdlib>
#include <cstring>
#include <string>
#include <vector>
#include <atomic>
#include <thread>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/mman.h>
 #include <sys/select.h>
#include "log/log.h"
#include "queue/sync_queue.hpp"
#include "drm/xf86drm.h"
#include "drm/xf86drmMode.h"
#include "drm/libdrm/drm_fourcc.h"

class SmartDrm {
private:
    typedef struct {
        uint32_t fb_id;
        void *ptr;
        uint64_t size;
        uint32_t pitch;
        uint32_t handle;
        uint32_t width;
        uint32_t height;
    } drm_buf_obj_t;

public:
    SmartDrm() {}
    ~SmartDrm() {}

    int init(uint32_t width, uint32_t height, uint32_t format = DRM_FORMAT_YUYV);
    int deinit();

    uint8_t* get_free_page(uint64_t* len);
    uint8_t* get_free_page_buf_id(uint64_t* len);
    int set_page_flip();
    int write_free_page_flip(uint8_t* buf, uint32_t len);

private:
    int drm_create_fb(drm_buf_obj_t* bo);
    int drm_destroy_fb(drm_buf_obj_t* bo);

private:
    std::atomic_bool m_loop_run;
    int m_fd{-1};
    drmModeRes *m_res{nullptr};
    drmModeCrtc* m_crtc{nullptr};
    uint32_t m_crtc_id{0};
    drmModeConnector *m_conn{nullptr};
    uint32_t m_conn_id{0};
    uint32_t m_conn_mode_id{0};

    drmEventContext m_event{0};
    drm_buf_obj_t m_buf_obj[2]{0};
    uint32_t m_format{0};
};